package by.parfen.messages.services.ver2;

import java.util.Random;

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class Client implements MessageListener {
	private static final int TIME_TO_LIVE = 60000;
	private static int ackMode;
	private static String clientQueueName;
	private static String messageBrokerUrl;

	private boolean transacted = false;
	private MessageProducer producer;

	static {
		messageBrokerUrl = "tcp://localhost:61616";
		clientQueueName = "by.parfen.messages.default";
		ackMode = Session.AUTO_ACKNOWLEDGE;
	}

	private ActiveMQConnectionFactory connectionFactory;
	private Connection connection;
	private Session session;
	private Destination adminQueue;
	private Destination tempDest;
	private MessageConsumer responseConsumer;

	private String lastTextMessage;

	public String getLastTextMessage() {
		return this.lastTextMessage;
	}

	public void setLastTextMessage(String lastTextMessage) {
		this.lastTextMessage = lastTextMessage;
	}

	public Client() {
		this.connectionFactory = new ActiveMQConnectionFactory(messageBrokerUrl);
		try {
			this.connection = this.connectionFactory.createConnection();
			this.connection.start();
			this.session = this.connection.createSession(transacted, ackMode);
			this.adminQueue = this.session.createQueue(clientQueueName);

			// Setup a message producer to send message to the queue the server is
			// consuming from
			this.producer = session.createProducer(adminQueue);
			this.producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

			// Create a temporary queue that this client will listen for responses on
			// then create a consumer
			// that consumes message from this temporary queue...for a real
			// application a client should reuse
			// the same temp queue for each message to the server...one temp queue per
			// client
			this.tempDest = session.createTemporaryQueue();
			this.responseConsumer = session.createConsumer(tempDest);

			// This class will handle the messages to the temp queue as well
			this.responseConsumer.setMessageListener(this);

		} catch (JMSException e) {
			// Handle the exception appropriately
		}
	}

	public void sendMessage(String textMessage) {
		try {
			// Now create the actual message you want to send
			TextMessage txtMessage = session.createTextMessage();
			txtMessage.setText("MyProtocolMessage. " + textMessage);

			// Set the reply to field to the temp queue you created above, this is the
			// queue the server
			// will respond to
			txtMessage.setJMSReplyTo(tempDest);

			// Set a correlation ID so when you get a response you know which sent
			// message the response is for
			// If there is never more than one outstanding message to the server then
			// the
			// same correlation ID can be used for all the messages...if there is more
			// than one outstanding
			// message to the server you would presumably want to associate the
			// correlation ID with this
			// message somehow...a Map works good
			String correlationId = this.createRandomString();
			txtMessage.setJMSCorrelationID(correlationId);
			this.producer.setTimeToLive(TIME_TO_LIVE);
			this.producer.send(txtMessage);
		} catch (JMSException e) {
			// Handle the exception appropriately
		}

	}

	private String createRandomString() {
		Random random = new Random(System.currentTimeMillis());
		long randomLong = random.nextLong();
		return Long.toHexString(randomLong);
	}

	public void onMessage(Message message) {
		String messageText = null;
		try {
			if (message instanceof TextMessage) {
				TextMessage textMessage = (TextMessage) message;
				messageText = textMessage.getText();
				System.out.println("received messageText = " + messageText);
				// this.responseConsumer.close();
			}
		} catch (JMSException e) {
			// Handle the exception appropriately
		}
		this.setLastTextMessage(messageText);
	}

}
